/*=============================================================================
#    The element-comm is a tentative program used to test our ideas.           
#                       Copyright (C)  bgao                                    
#
#     This program is free software; you can redistribute it and/or            
#      modify it under the terms of the GNU General Public License             
#     as published by the Free Software Foundation; either version 2           
#         of the License, or (at your option) any later version.               
#
#     This program is distributed in the hope that it will be useful,          
#    but WITHOUT ANY WARRANTY; without even the implied warranty of           
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            
#             GNU General Public License for more details.                    
#
#    You should have received a copy of the GNU General Public License        
#     along with this program; if not, write to the Free Software             
#      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,             
#                       MA  02110-1301, USA.                                  
#==============================================================================
# $Id$ 
#
# $Author$ 
#
# $Revision$ 
#
# $Date$ 
#
# Description: 
#
=============================================================================*/
#ifndef __CC2420_H
#define __CC2420_H


#include "wsn-platform.h"
#include "wsn-cpu.h"
#ifdef _AVR_
#include "AVR/avr-common.h"
#endif
#ifdef _ARM_
#include "ARM/arm-common.h"
#endif
#ifdef _Debug_zigbee_
#include "zigbee.h"
#endif

void cc2420_change_reg(uint8 addr,uint8 shift,uint16 mask,uint16 value);
uint8 cc2420_command(uint8 cmd);
uint16 cc2420_read_register(uint8 addr);
void cc2420_write_register(uint8 addr, uint16 value);
void cc2420_read_ram(uint16 addr, uint8 len, uint8 *buf);
void cc2420_write_ram(uint16 addr, uint8 len, uint8 *buf);
uint8 cc2420_read_fifo(uint8 *buf, uint8 len);
void cc2420_write_fifo(uint8 *buf, uint8 len);
void cc2420_flush_Rxfifo(void);


void cc2420_Oscillator_TurnOn(void);
void cc2420_reset(void);
uint8 cc2420_random_byte(void);
void cc2420_enable_fifop(void);
void cc2420_disable_fifop(void);



#define cc2420_flush_Txfifo() 	cc2420_command(CC2420_SFLUSHTX)
#define cc2420_status()			cc2420_command(CC2420_SNOP)


#define POSSIBLE_CHANNEL_MASK 0x07FFF800 //???

/* strobe command registers */
#define CC2420_SNOP					0x00
#define CC2420_SXOSCON				0x01
#define CC2420_STXCAL				0x02
#define CC2420_SRXON				0x03
#define CC2420_STXON				0x04
#define	CC2420_STXONCCA				0x05
#define CC2420_SRFOFF				0x06
#define CC2420_SXOSCOFF				0x07
#define CC2420_SFLUSHRX				0x08
#define CC2420_SFLUSHTX				0x09
#define CC2420_SACK					0x0A
#define CC2420_SACKPEND				0x0B
#define CC2420_SRXDEC				0x0C
#define CC2420_STXENC				0x0D
#define CC2420_SAES					0x0E

/* configuration registers */
#define CC2420_REG_MAIN				0x10
#define CC2420_REG_MDMCTRL0			0x11
#define CC2420_REG_MDMCTRL1			0x12
#define CC2420_REG_RSSI_CCA			0x13
#define CC2420_REG_SYNCWORD			0x14
#define CC2420_REG_TXCTRL			0x15
#define CC2420_REG_RXCTRL0			0x16
#define CC2420_REG_RXCTRL1			0x17
#define CC2420_REG_FSCTRL			0x18
#define CC2420_REG_SECCTRL0			0x19
#define CC2420_REG_SECCTRL1			0x1A
#define CC2420_REG_BATTMON			0x1B
#define CC2420_REG_IOCFG0			0x1C
#define CC2420_REG_IOCFG1			0x1D
#define CC2420_REG_MANFIDL			0x1E
#define CC2420_REG_MANFIDH			0x1F
#define CC2420_REG_FSMTC			0x20
#define CC2420_REG_MANAND			0x21
#define CC2420_REG_MANOR			0x22
#define CC2420_REG_AGCCTRL			0x23
#define CC2420_REG_AGCTST0			0x24
#define CC2420_REG_AGCTST1			0x25
#define CC2420_REG_AGCTST2			0x26
#define CC2420_REG_FSTST0			0x27
#define CC2420_REG_FSTST1			0x28
#define CC2420_REG_FSTST2			0x29
#define CC2420_REG_FSTST3			0x2A
#define CC2420_REG_RXBPFTST			0x2B
#define CC2420_REG_FSMSTATE			0x2C
#define CC2420_REG_ADCTST			0x2D
#define CC2420_REG_DACTST			0x2E
#define CC2420_REG_TOPTST			0x2F
#define CC2420_REG_RESERVED			0x30

/* FIFO registers */
#define CC2420_TXFIFO				0x3E
#define CC2420_RXFIFO				0x3F

/*RAM access address*/
#define CC2420_RAM_SHORTADR			0x16A
#define CC2420_RAM_PANID			0x168
#define CC2420_RAM_IEEEADR			0x160
#define CC2420_RAM_CBCSTATE			0x150
#define CC2420_RAM_TXNONCE			0x140
#define CC2420_RAM_TXCTR			0x140
#define CC2420_RAM_SABUF			0x120
#define CC2420_RAM_RXNONCE			0x110
#define CC2420_RAM_RXCTR			0x110
#define CC2420_RAM_KEY0				0x100
#define CC2420_RAM_RXFIFO			0x080
#define CC2420_RAM_TXFIFO			0x000

/* Main state  status byte*/
#define CC2420_MS_RSSI_VALID				0x02
#define CC2420_MS_LOCK						0x04	
#define CC2420_MS_TX_ACTIVE					0x08
#define CC2420_MS_ENC_BUSY					0x10
#define CC2420_MS_TX_UNDERFLOW				0x20
#define CC2420_MS_XOSC16M_STABLE			0x40

/* MDMCTRL0 */
#define CC2420_MC0_RESET_VALUE				0x0AE2
#define CC2420_MC0_PREAMBLE_LENGTH_MASK		0x000F
#define CC2420_MC0_AUTOACK_MASK				0x0010
#define CC2420_MC0_AUTOCRC					0x0020
#define CC2420_MC0_CCA_MODE_MASK			0x00C0
#define CC2420_MC0_CCA_HYST_MASK			0x0700
#define CC2420_MC0_ADR_DECODE				0x0800
#define CC2420_MC0_ADR_DECODE_MASK			(1<<11)
#define CC2420_MC0_PAN_COORDINATOR			0x1000
#define CC2420_MC0_PAN_COORDINATOR_SHIFT	12
#define CC2420_MC0_PAN_COORDINATOR_MASK		(1<<CC2420_MC0_PAN_COORDINATOR_SHIFT)
#define CC2420_MC0_PRESERVED_FRAME_MODE		0x2000

/* MDMCTRL1 */
#define CC2420_MC1_RESET_VALUE				0x0000
//#define RX_MODE(x) 						((x) << 0)
//#define RX_MODE_INFINITE_RECEPTION		RX_MODE(2)
//#define RX_MODE_NORMAL_OPERATION		RX_MODE(0)

/* RSSI and CCA register */
#define CC2420_RSSI_VAL_MASK				0x007F //??
#define CC2420_CCA_THR_MASK					0xFF00 //??
#define CC2420_CCA_THR_SHIFT				8 //?
#define CC2420_RSSI_OFFSET					-45

/* TXCTRL */
#define CC2420_TXCTRL_BASE_VALUE			0xA020  /* bit 5 "must be 1" */
#define CC2420_TXCTRL_TXPOWER_MASK			0x001F

/* RXCTRL1 */
#define CC2420_RXCTRL1_RESET_VALUE			0x0A56
#define CC2420_RXCTRL1_RXBPF_LOCUR			0x2000 /* recommended setting */
#define CC2420_RXCTRL1_INIT_VALUE			(CC2420_RXCTRL1_RESET_VALUE | CC2420_RXCTRL1_RXBPF_LOCUR)

/* FSCTRL */
#define CC2420_FSCTRL_BASE_VALUE			0x4000
#define CC2420_FSCTRL_FREQ_2405MHZ			357

/* IOCFG0 */
#define CC2420_IOC0_BASE_VALUE				0x0000
#define CC2420_IOC0_BCN_ACCEPT				0x0800
#define CC2420_IOC0_FIFOPOLARITY			0x0400 //active low
#define CC2420_IOC0_FIFOP_POLARITY			0x0200 //active low
#define CC2420_IOC0_SFD_POLARITY			0x0100 //active low
#define CC2420_IOC0_CCA_POLARITY			0x0080 //active low
#define CC2420_IOC0_FIFOP_THR_RESET_VALUE	64

#define CC2420_IOC0_FIFOP_THR				0x0070 //112 bytes in RXFIFO to active FIFOP
#define CC2420_IOC0_FIFOP_THR_MASK			0x007F

/* IOCFG1 */
#define CC2420_IG1_RESET_VALUE				0x0000
#define CC2420_IG1_CCAMUX_ADC_Q0			1
#define CC2420_IG1_CCAMUX_XOSC16M_STABLE	24

/* MANFIDL */
#define CC2420_MANFIDL_RESET_VALUE			0x233D

/* MANAND */
#define CC2420_MANAND_RESET_VALUE			0xFFFF
#define CC2420_ADC_PD						0x0008
#define CC2420_VGA_PD						0x0004
#define CC2420_RXBPF_PD						0x0002

/* FSMSTATE */
#define CC2420_FSM_FFCTRL_STATE_RX_INF		31 /* not documented in data sheet */

/************************************************************
 *                       cc2420 control function
 ***********************************************************/

#define CC2420_CS_ENABLE()			( PORT_2420_CS &= ~BIT_SET(CSN) )
#define CC2420_CS_DISABLE()			( PORT_2420_CS |=  BIT_SET(CSN) )

#define CC2420_VREG_ACTIVE()		( PORT_2420_VREG |= BIT_SET(VREG_EN) )
#define CC2420_VREG_INACTIVE()		( PORT_2420_VREG &= ~BIT_SET(VREG_EN) )

#define CC2420_RESET_ACTIVE()		( PORT_2420_RESET &= ~BIT_SET(RESET_N) )
#define CC2420_RESET_INACTIVE()		( PORT_2420_RESET |=  BIT_SET(RESET_N) )

#define CC2420_READ_PIN(x)			( PORT_2420_##x & BIT_SET(x))


#define CC2420_FIFO_IS_ACTIVE()		( CC2420_READ_PIN(FIFO) ==0 )
#define CC2420_RX_IS_OVERFLOW()		( CC2420_READ_PIN(FIFOP) == 0 /* FIFOP flag */ && CC2420_READ_PIN(FIFO) !=0 /* FIFO flag */)
#define CC2420_TX_IS_UNDERFLOW()	( cc2420_status() & CC2420_MS_TX_UNDERFLOW )
#define CC2420_CCA_CHECK()			( CC2420_READ_PIN(CCA) != 0 )
#define CC2420_CCA_IS_ACTIVE()		(CC2420_READ_PIN(CCA) == 0)
#define CC2420_SFD_IS_ACTIVE()		(CC2420_READ_PIN(SFD) == 0)
#define CC2420_WAIT_RSSI_VALID()	while(!(cc2420_status() & CC2420_MS_RSSI_VALID))
#define CC2420_WAIT_TX_END()		while(cc2420_status() & CC2420_MS_TX_ACTIVE)

/************************************************************
 *                       cc2420 error number
 ***********************************************************/

#define	EUNDERFLOW          40			/*TXFIFO underflow*/
#define	EOVERFLOW			41          /*RXFIFO overflow */
#define ECHNLBUSY		    42	        /*cca failed  */




#endif
